import request from "../../utils/request"

Page({
  /**
   * 页面的初始数据
   */
  data: {
    videoGroupList: [], // 获取导航数据 
    navId: '', // 导航的标识
    videoList: [], // 视频列表数据
    videoUpdateTime: [], // 记录video播放的时长
    isTriggered: false, // 标识下拉刷新是否被触发
    isTriggeredflag: false, // 下拉触底的节流
    offsetCount: 0, // 已经获取过的视频偏移量、总量
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 获取导航数据
    this.getVideoGroupListData()
  },

  // 获取导航数据
  async getVideoGroupListData() {
    let videoGroupListData = await request('/video/group/list')
    this.setData({
      videoGroupList: videoGroupListData.data.slice(0, 14),
      navId: videoGroupListData.data[0].id,
    })

    // 获取视频列表数据
    this.getVideoList(this.data.navId);
  },
  // 获取视频列表数据【由于没有视频地址，还需要获取拼接】
  async getVideoList(navId, isToLower = false) {
    // 正在上拉触底
    this.setData({ isTriggeredflag: true })

    // 判断navId为空串的情况
    if (!navId) return;

    let videoListData = await request('/video/group', { id: navId, offset: this.data.offsetCount });
    // 关闭消息提示框
    wx.hideLoading();

    // 有的可能为空，没有视频
    if (!videoListData.hasmore) {
      wx.showToast({
        icon: "none",
        title: '当前视频标签下暂无视频，请查看其他视频标签中视频',
      })
      return;
    }

    let index = this.data.offsetCount
    /* 使用Promise.all
      由于 map 方法的回调函数是异步函数，它返回的是一个 Promise 对象数组，而不是处理后的值数组。为了正确获取处理后的值，需要等待 map 方法中的所有异步操作完成。使用 Promise.all 方法来等待所有 Promise 对象解决，并获取它们的结果。
    */
    let videoList = await Promise.all(videoListData.datas.map(async (item) => {
      item.id = index++;
      // 视频地址为null，就去获取
      if (item.data.urlInfo == null) {
        let videoUrl = await request('/video/url', { id: item.data.vid });
        item.data.urlInfo = videoUrl.urls[0];
      }
      return item;
    }));

    // 计算视频总获取量
    let offsetCount = this.data.offsetCount + videoList.length
    this.setData({ offsetCount, isTriggeredflag: false })

    // 如果触发的是下拉触底事件，就不走下面this.setData了，直接返回数据
    if (isToLower) {
      return videoList;
    }

    this.setData({
      videoList,
      isTriggered: false // 关闭下拉刷新
    })
  },

  // 点击切换导航的回调【清空视频列表，获取新的列表】
  changeNav(event) {
    //let navId = event.currentTarget.id; // 通过id向event传参的时候如果传的是number会自动转换成string，navId>>>0, 右移0位，非number转为number
    let navId = event.currentTarget.dataset.id;
    this.setData({
      navId: navId,
      videoList: [],
      // 切换把上一个nav的总量和节流状态改变为原状态
      offsetCount: 0,
      isTriggeredflag: false
    })
    // 显示正在加载
    wx.showLoading({
      title: '正在加载'
    })
    // 动态获取当前导航对应的视频数据
    this.getVideoList(this.data.navId);
  },

  // 点击播放/继续播放的回调
  handlePlay(event) {
    /* 问题： 多个视频同时播放的问题
    * 需求：
    *   1. 在点击播放的事件中需要找到上一个播放的视频
    *   2. 在播放新的视频之前关闭上一个正在播放的视频
    * 关键：
    *   1. 如何找到上一个视频的实例对象
    *   2. 如何确认点击播放的视频和正在播放的视频不是同一个视频
    * 单例模式：
    *   1. 需要创建多个对象的场景下，通过一个变量接收，始终保持只有一个对象，
    *   2. 节省内存空间
    * */

    let vid = event.currentTarget.id;

    // 关闭上一个播放的视频
    // this.vid !== vid && this.videoContext && this.videoContext.stop();
    if (this.vid !== vid) {
      if (this.videoContext) {
        // 关闭视频
        this.videoContext.stop()
      }
    }
    this.vid = vid;

    // 创建控制video标签的实例对象
    this.videoContext = wx.createVideoContext(vid);
    // 判断当前的视频之前是否播放过，是否有播放记录, 如果有，跳转至指定的播放位置
    let { videoUpdateTime } = this.data;
    // 查询到 find()第一个video元素的值。没有返回 undefined
    let videoItem = videoUpdateTime.find(item => item.vid === vid);
    if (videoItem) {
      // 查询有，跳转到指定位置，单位 s
      this.videoContext.seek(videoItem.currentTime);
    }
    // 播放视频
    this.videoContext.play();
  },

  /* 思路： 判断记录播放时长的videoUpdateTime数组中是否有当前视频的播放记录
    *   1. 如果有，在原有的播放记录中修改播放时间为当前的播放时间
    *   2. 如果没有，需要在数组中添加当前视频的播放对象
    * */
  // 监听视频播放进度的回调
  handleTimeUpdate(event) {
    let { videoUpdateTime } = this.data;

    let videoItem = videoUpdateTime.find(item => item.vid === event.currentTarget.id);
    if (videoItem) { // 之前有
      videoItem.currentTime = event.detail.currentTime;
    } else { // 之前没有
      let videoTimeObj = {
        vid: event.currentTarget.id,
        currentTime: event.detail.currentTime
      };
      videoUpdateTime.push(videoTimeObj);
    }
    // 更新videoUpdateTime的状态
    this.setData({
      videoUpdateTime
    })
  },

  // 视频播放结束调用的回调
  handleEnded(event) {
    // 移除记录播放时长数组中当前视频的对象
    let { videoUpdateTime } = this.data;
    // 查询到 findIndex()第一个元素值的下标。没有返回 undefined
    videoUpdateTime.splice(videoUpdateTime.findIndex(item => item.vid === event.currentTarget.id), 1);
    this.setData({
      videoUpdateTime
    })
  },

  // 自定义下拉刷新的回调： scroll-view
  handleRefresher() {
    // 再次发请求，获取最新的视频列表数据
    this.getVideoList(this.data.navId);
  },

  // 自定义上拉触底的回调 scroll-view
  async handleToLower() {
    // 快速上拉触底，可能导致key没来得及更新，可能导致重复
    if (this.data.isTriggeredflag) return;

    // 再次发请求，获取最新的视频列表数据，先获取之前的视频数组，
    let videoList = this.data.videoList;
    let newVideoList = await this.getVideoList(this.data.navId, true);
    videoList.push(...newVideoList)

    this.setData({
      videoList
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function ({ from, target }) {
    if (from === 'button') {
      return {
        title: target.dataset.title,
        page: '/pages/community/community',
        imageUrl: target.dataset.id
      }
    } else {
      return {
        title: '快来观看更多精彩视频',
        page: '/pages/community/community',
      }
    }
  }
})